using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace XDL.Framework
{
    /// <summary>
    /// Support a simple timer.
    /// </summary>
    public class Timer
    {
        TimeSpan m_t;
        TimeSpan m_initialTime;
        bool m_isSignaled = false;
        bool m_isActive = true;

        /// <summary>
        /// Default initializer.
        /// </summary>
        public Timer():
            this(TimeSpan.Zero,false)
        {
        }

        /// <summary>
        /// Creates a new timer with a given frequency <paramref name="t"/>.
        /// </summary>
        /// <param name="t">Timer frequency</param>
        public Timer(TimeSpan t):
            this(t,true)
        {
        }

        /// <summary>
        /// Creates a new timer with a predefined active/inactive state.
        /// </summary>
        /// <param name="t">Timer frequency</param>
        /// <param name="activeState">Initial state</param>
        public Timer(TimeSpan t, bool activeState)
        {
            m_initialTime = t;
            if (activeState)
            {
                m_t = m_initialTime;
            }
            else
            {
                m_t = TimeSpan.Zero;
                m_isActive = false;
            }
        }

        /// <summary>
        /// Restart timer
        /// </summary>
        public void Reset()
        {
            m_t = m_initialTime;
            m_isSignaled = false;
            m_isActive = true;
        }

        /// <summary>
        /// Stop the timer
        /// </summary>
        public void Stop()
        {
            m_t = TimeSpan.Zero;
            m_isActive = false;
        }

        /// <summary>
        /// Starts the timer (does nothing if the timer was already started)
        /// </summary>
        public void Start()
        {
            if (!m_isActive)
            {
                Reset();
            }
        }

        /// <summary>
        /// Restart timer with a new timespan.
        /// </summary>
        public void Reset(TimeSpan t)
        {
            m_initialTime = t;
            Reset();
        }

        /// <summary>
        /// Update timer state
        /// </summary>
        /// <param name="gameTime"></param>
        public void Update(GameTime gameTime)
        {
            m_isSignaled = false;
            if (m_isActive)
            {
                m_t -= gameTime.ElapsedGameTime;
                if (m_t <= TimeSpan.Zero)
                {
                    m_isSignaled = true;
                    m_isActive = false;
                }
            }
        }
        /// <summary>
        /// Indicates whether the timer lapsed during the last update
        /// </summary>
        public bool IsSignaled
        {
            get { return m_isSignaled; }
        }

        /// <summary>
        /// Indicates whether the timer is still active.
        /// </summary>
        public bool IsActive
        {
            get { return m_isActive; }
        }

        /// <summary>
        /// Returns the "age" of the timer between [0;1]
        /// </summary>
        public float NormalizedAge
        {
            get { return 1.0f - (float)(m_t.TotalSeconds / m_initialTime.TotalSeconds); }
        }
    }
}
